/**
 * HTTP 请求封装
 * 基于 uni.request 封装，提供统一的请求接口
 */

// 获取 API 地址和超时配置
const getApiUrl = () => {
  // #ifdef H5
  return import.meta.env.VITE_APP_API_URL
  // #endif

  // #ifndef H5
  return process.env.VITE_APP_API_URL
  // #endif
}

const getTimeout = () => {
  // #ifdef H5
  return import.meta.env.DEV ? 10000 : 15000
  // #endif

  // #ifndef H5
  return 15000
  // #endif
}

const apiUrl = getApiUrl()
const timeout = getTimeout()

/**
 * 请求方法枚举
 */
export const Method = {
  GET: 'GET',
  POST: 'POST',
  PUT: 'PUT',
  DELETE: 'DELETE',
  PATCH: 'PATCH'
}

/**
 * 请求拦截器配置
 */
const requestInterceptor = {
  /**
   * 请求前处理
   * @param {Object} config 请求配置
   * @returns {Object} 处理后的配置
   */
  onRequest(config) {
    // 添加 token
    const token = uni.getStorageSync('token') || ''
    if (token) {
      config.header = config.header || {}
      config.header['Authorization'] = `Bearer ${token}`
    }

    // 添加通用请求头
    config.header = {
      'Content-Type': 'application/json',
      ...config.header
    }

    // 添加时间戳防止缓存
    if (config.method === 'GET') {
      config.url += (config.url.includes('?') ? '&' : '?') + `_t=${Date.now()}`
    }

    return config
  },

  /**
   * 请求错误处理
   * @param {Error} error 错误信息
   */
  onError(error) {
    console.error('请求错误:', error)
    uni.showToast({
      title: '网络请求失败',
      icon: 'none',
      duration: 2000
    })
  }
}

/**
 * 响应拦截器配置
 */
const responseInterceptor = {
  /**
   * 响应成功处理
   * @param {Object} response 响应数据
   * @returns {*} 处理后的数据
   */
  onSuccess(response) {
    const { statusCode, data } = response

    // HTTP 状态码检查
    if (statusCode >= 200 && statusCode < 300) {
      // 业务状态码检查（根据后端返回的数据结构调整）
      if (data.code === 200 || data.success) {
        return data.data || data
      } else if (data.code === 401) {
        // token 过期或未登录
        uni.removeStorageSync('token')
        uni.showToast({
          title: data.message || '登录已过期',
          icon: 'none'
        })
        // 跳转到登录页
        uni.reLaunch({
          url: '/pages/login/index'
        })
        return Promise.reject(new Error(data.message || '登录已过期'))
      } else {
        // 业务错误
        uni.showToast({
          title: data.message || '请求失败',
          icon: 'none'
        })
        return Promise.reject(new Error(data.message || '请求失败'))
      }
    } else {
      // HTTP 错误
      uni.showToast({
        title: `请求失败 (${statusCode})`,
        icon: 'none'
      })
      return Promise.reject(new Error(`HTTP Error: ${statusCode}`))
    }
  },

  /**
   * 响应错误处理
   * @param {Error} error 错误信息
   */
  onError(error) {
    console.error('响应错误:', error)
    uni.showToast({
      title: error.message || '网络请求失败',
      icon: 'none',
      duration: 2000
    })
    return Promise.reject(error)
  }
}

/**
 * 统一请求方法
 * @param {Object} options 请求配置
 * @returns {Promise} 请求结果
 */
function request(options = {}) {
  const { url, method = Method.GET, data = {}, header = {}, timeout: requestTimeout = timeout, loading = true, loadingText = '加载中...', ...rest } = options

  // 显示加载提示
  if (loading) {
    uni.showLoading({
      title: loadingText,
      mask: true
    })
  }

  // 请求拦截
  const config = requestInterceptor.onRequest({
    url: url.startsWith('http') ? url : `${apiUrl}${url}`,
    method,
    data,
    header,
    timeout: requestTimeout,
    ...rest
  })

  return new Promise((resolve, reject) => {
    uni.request({
      ...config,
      success: (response) => {
        requestInterceptor.onError(null) // 重置错误状态
        try {
          const result = responseInterceptor.onSuccess(response)
          resolve(result)
        } catch (error) {
          responseInterceptor.onError(error)
          reject(error)
        }
      },
      fail: (error) => {
        requestInterceptor.onError(error)
        responseInterceptor.onError(error)
        reject(error)
      },
      complete: () => {
        // 隐藏加载提示
        if (loading) {
          uni.hideLoading()
        }
      }
    })
  })
}

/**
 * GET 请求
 */
export const get = (url, params = {}, options = {}) => {
  return request({
    url,
    method: Method.GET,
    data: params,
    ...options
  })
}

/**
 * POST 请求
 */
export const post = (url, data = {}, options = {}) => {
  return request({
    url,
    method: Method.POST,
    data,
    ...options
  })
}

/**
 * PUT 请求
 */
export const put = (url, data = {}, options = {}) => {
  return request({
    url,
    method: Method.PUT,
    data,
    ...options
  })
}

/**
 * DELETE 请求
 */
export const del = (url, data = {}, options = {}) => {
  return request({
    url,
    method: Method.DELETE,
    data,
    ...options
  })
}

/**
 * PATCH 请求
 */
export const patch = (url, data = {}, options = {}) => {
  return request({
    url,
    method: Method.PATCH,
    data,
    ...options
  })
}

export default request
